package io.terminus.spzx.manager.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.util.ListUtils;
import io.terminus.spzx.manager.mapper.CategoryMapper;
import io.terminus.spzx.model.entity.product.Category;
import org.springframework.beans.BeanUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author lichunlong lcl253137@alibaba-inc.com
 * @Desc Alibaba Easy Excel监听器
 * @Date 2024-10-02
 */
public class EasyExcelListener<CategoryExcelVo> extends AnalysisEventListener<CategoryExcelVo> {

    /**
     * 每隔100条存储数据库, 方便内存回收
     */
    private static final int BATCH_COUNT = 100;

    private CategoryMapper categoryMapper;

    /**
     * 缓存数据
     */
    private List<CategoryExcelVo> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

    /**
     * Listener不能让Spring管理: <a href="">https://easyexcel.opensource.alibaba.com/qa/read</a>
     *
     * @param categoryMapper 通过构造器注入
     */
    public EasyExcelListener(CategoryMapper categoryMapper) {
        this.categoryMapper = categoryMapper;
    }

    @Override
    public void invoke(CategoryExcelVo data, AnalysisContext context) {
        cachedDataList.add(data);
        // 达到BATCH_COUNT需要存储一次数据库。防止数据几万条数据在内存OOM
        if (cachedDataList.size() >= BATCH_COUNT) {
            saveData();
            // 清空list集合
            cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 确保最后遗留的数据也落库
        saveData();
    }

    /**
     * 保存类目
     */
    private void saveData() {
        // Category Excel Vo List -> Category List
        List<Category> categoryList = new ArrayList<>();
        for (CategoryExcelVo categoryExcelVo : cachedDataList) {
            Category category = new Category();
            BeanUtils.copyProperties(categoryExcelVo, category);
            categoryList.add(category);
        }

        categoryMapper.batchInsert(categoryList);
    }
}
